/**
 * @author yaoyuan
 * @version 1.0
 * @name zjzcVotingApp.Service: uiService
 * @description uiService
 */
'use strict';

angular.module('zjzcVotingApp')
    .service('uiService', ['$rootScope', '$window', 'http', '$uibModal', function($rootScope, $window, http, $uibModal) {

        //-------------- DOM操作的兼容性方法 --------------
        var appDom = (function() {
            return {
                nextElementSibling: function(element) {
                    var _next = function(element) {
                        var nextElement = element.nextSibling;
                        if(!nextElement || nextElement.nodeType === 1) return nextElement;
                        else  return _next(nextElement);
                    }
                    return _next(element);
                },
                previousElementSibling: function(element) {
                    var _previous = function(element) {
                        var previousElement = element.previousSibling;
                        if(!previousElement || previousElement.nodeType === 1) return previousElement;
                        else return _previous(previousElement);
                    }
                    return _previous(element);
                }
            };
        })();
        //-------------- AJAX请求模式模块 --------------
        var appAjax = (function() {
            /**
             * [_addConfig 添加必要的配置参数]
             */
            var _addConfig = function(config) {
                if(appCommon.type(config) == 'string') {
                    config = {
                        url: config,
                        module: 'default'
                    };
                }
                config.module =  config.module || 'default';
                return config;
            }
            /**
             * [_module 请求模式]
             * 根据接口的module配置寻找适用的请求模式
             * 默认为default或者自动添加该模式
             */
            var _module = {
                /**
                 * [base 基本请求模式]
                 */
                base: function(params, config) {
                    var params = params || {};
                    params.method = config.url;
                    if(config.params) {
                        params = angular.extend(config.params, params);
                    }
                    if(config.method && config.method.toLowerCase() == 'post') {
                        return http.post(params);
                    }
                    return http.ajax(params);
                },
                /**
                 * [default 默认模式]
                 *  支持示例如下
                 *  1. key: url // url 为接口地址
                 *  2. key: {
                 *      url: url,
                 *      method: 'post',     //可选  请求方式默认为get
                 *      module: 'default'   //可选  默认为default
                 *      params: {key: val}  //可选  额外添加的参数
                 *     }
                 */
                default: function(config) {
                    return function(params) {
                        return _module.base(params, config);
                    }
                },
                /**
                 * [parameter 单参数模式]
                 * 支持示例如下
                 * 1. key: {
                 *      url: url,
                 *      method: 'post',     //可选  请求方式默认为get
                 *      module: 'parameter'
                 *      parameter: key  //必选 传值对于的key对象
                 *     }
                 */
                parameter: function(config) {
                    return function(val) {
                        var params = {};
                        params[config.parameter] = val;
                        return _module.base(params, config);
                    }
                },
                /**
                 * [method 调用方法模式]
                 * 支持示例如下
                 * 1. key: {
                 *      url: url,           //必选  二次调用改服务中以url为关键key值的方法
                 *      method: 'post',     //可选  请求方式默认为get
                 *      module: 'method'
                 *      params: {key: val}  //可选  额外添加的参数
                 *     }
                 */
                method: function(config, configs) {
                    return function(params) {
                        var params = params || {};
                        if(config.params) {
                            params = angular.extend(config.params, params);
                        }
                        var _config = configs[config.url];
                        if(appCommon.type(_config) == 'function') {
                            return configs[config.url](params);
                        }else{
                            _config = _addConfig(_config);
                            return _module[_config.module](_config, configs)(params);
                        }
                    }
                }
            };

            return {
                ajaxModule: function(configs) {
                    var _obj = {};
                    for(var i in configs) {
                        configs[i] = _addConfig(configs[i]);
                        //console.log(i);
                        _obj[i] = _module[configs[i].module](configs[i], configs);
                    }
                    return _obj;
                }
            };
        })();
        //-------------- 公共模块的方法 --------------
        var appCommon = (function() {

            var classtype = {};
            // Populate the classtype map
            "Boolean Number String Function Array Date RegExp Object".split(" ").forEach(function(name, i) {
                classtype["[object " + name + "]"] = name.toLowerCase();
            });
            // String format
            String.format = function(format){
                var args = Array.prototype.slice.call(arguments, 1);
                return format.replace(/\{(\d+)\}/g, function(m, i){
                    return args[i];
                });
            }
            String.prototype.formatDate = function() {
                return this.replace(/-/g, "/");
            }
            String.prototype.toShortDate = function() {
                return this.split(' ')[0];
            }
            // array map
            if(!Array.prototype.map) {
                Array.prototype.map = function(callback, thisArg) {
                    var T, A, k;
                    if(this == null) {
                        throw new TypeError(' this is null or not defined');
                    }
                    var O = Object(this);
                    var len = O.length >>> 0;
                    if(typeof callback !== 'function') {
                        throw new TypeError(callback + ' is not a function');
                    }
                    if(arguments.length > 1) {
                        T = thisArg;
                    }
                    A = new Array(len);
                    k = 0;
                    while (k < len) {
                        var kValue, mappedValue;
                        if (k in O) {
                            kValue = O[k];
                            mappedValue = callback.call(T, kValue, k, O);
                            A[k] = mappedValue;
                        }
                        k++;
                    }
                    return A;
                };
            }
            // array filter
            if(!Array.prototype.filter) {
                Array.prototype.filter = function(fun/*, thisArg*/) {
                    if(this === void 0 || this === null) {
                        throw new TypeError();
                    }
                    var t = Object(this);
                    var len = t.length >>> 0;
                    if (typeof fun !== 'function') {
                        throw new TypeError();
                    }
                    var res = [];
                    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
                    for(var i = 0; i < len; i++) {
                        if (i in t) {
                            var val = t[i];
                            if(fun.call(thisArg, val, i, t)) {
                                res.push(val);
                            }
                        }
                    }
                    return res;
                };
            }
            return {
                // get 请求的 数据和url 拼接
                splitGet: function(url, datas) {
                    var strs = "";
                    if((typeof datas).toLocaleLowerCase() !== 'object') strs = datas;
                    else {
                        var str=[];
                        for(var p in datas){
                            str.push(encodeURIComponent(p)+'='+encodeURIComponent(datas[p]))
                        }
                        strs = str.join('&');
                    }
                    return url + "?" + strs;
                },
                getSelect: function(arr, list) {
                    var index = arr.indexOf(list);
                    if (index !== -1) {
                        arr.splice(index, 1);
                    } else {
                        arr.push(list);
                    }
                    return arr;
                },
                //解决js浮点运算bug
                /* 除 */
                accDiv: function(arg1, arg2) {
                    var t1 = 0,
                        t2 = 0,
                        r1, r2;
                    try {
                        t1 = arg1.toString().split(".")[1].length
                    } catch (e) {}
                    try {
                        t2 = arg2.toString().split(".")[1].length
                    } catch (e) {}
                    r1 = Number(arg1.toString().replace(".", ""))
                    r2 = Number(arg2.toString().replace(".", ""))
                    return (r1 / r2) * Math.pow(10, t2 - t1);
                },
                /* 乘 */
                accMul: function(arg1, arg2) {
                    var m = 0,
                        s1 = arg1.toString(),
                        s2 = arg2.toString();
                    try {
                        m += s1.split(".")[1].length
                    } catch (e) {}
                    try {
                        m += s2.split(".")[1].length
                    } catch (e) {}
                    return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
                },
                compareGreaterTime: function(date1, date2) {
                    var _date1 = new Date(date1.formatDate()).getTime();
                    var _date2 = new Date(date2.formatDate()).getTime();
                    return _date1 > _date2;
                },
                compareLittleTime: function(date1, date2) {
                    var _date1 = new Date(date1.formatDate()).getTime();
                    var _date2 = new Date(date2.formatDate()).getTime();
                    return _date1 < _date2;
                },
                addLoading: function() {
                    angular.element('.shade-layer').css({'height': document.body.scrollHeight + 'px'}).removeClass('ng-hide').addClass('ng-show');
                },
                removeLoading: function() {
                    angular.element('.shade-layer').removeClass('ng-show').addClass('ng-hide');
                },
                formatDate: function(date, flag){
                    var now = new Date(date);
                    var year = now.getFullYear();
                    var month = now.getMonth() < 9 ? '0'+ (now.getMonth()+1) : now.getMonth()+1;
                    var date = now.getDate() < 10 ? '0'+now.getDate() : now.getDate();
                    var hour = now.getHours();
                    var minute = now.getMinutes();
                    var second = now.getSeconds();
                    if(flag){
                        return year + '-' + month + '-' + date + ' ' +hour+':'+minute+':'+second;
                    } else {
                        return year + '-' + month + '-' + date;
                    }

                },
                combine: function(obj, sign) {
                    sign = sign || ',';
                    var datas = "";
                    for(var i in obj) {
                        if(obj[i]) datas += i + ',';
                    }
                    return datas.substr(0,datas.length-1);
                },
                // extend: function(_this, currObj, theObj) {},
                type: function(obj) {
                    return obj == null ? String(obj) : (classtype[Object.prototype.toString.call(obj)] || "object");
                }
            }
        })();
        //------------------- window信息提示-------------------
        var appWindow = (function() {

            return {
                // window.alert
                ALERT: function(msg, options) {
                    var modal = $uibModal.open({
                        templateUrl: 'appCache/uiAlert.html',
                        backdrop: 'static',
                        keyboard: !1,
                        controller: ['$scope', '$uibModalInstance', 'message', 'options', function($scope, $uibModalInstance, message, options){
                            $scope.message = message;
                            $scope.headerTxt = options.headTxt || '系统提示';
                            $scope.className = options.bcolor || '';
                            $scope.ok = function () {
                                $uibModalInstance.close();
                            }
                        }],
                        resolve: {
                            'message':function(){
                                return msg || '暂无信息';
                            },
                            options: function() {
                                return options || {};
                            }
                        }
                    });
                    return modal.result;
                },
                // window.confirm
                CONFIRM: function(msg, options) {
                    var modal = $uibModal.open({
                        templateUrl: 'appCache/uiConfirm.html',
                        backdrop: 'static',
                        keyboard: !1,
                        controller: ['$scope', '$uibModalInstance', 'message', 'options', function($scope, $uibModalInstance, message, options){
                            $scope.message = message;
                            $scope.headerTxt = options.headTxt || '系统提示';
                            $scope.className = options.bcolor || '';
                            $scope.ok = function () {
                                $uibModalInstance.close();
                            };
                            $scope.cancel = function () {
                                $uibModalInstance.dismiss('cancel');
                            }
                        }],
                        resolve: {
                            'message':function(){
                                return msg;
                            },
                            options: function() {
                                return options || {};
                            }
                        }
                    });
                    return modal.result;
                },
                LOADING: function(options) {
                    if(!options) return;
                    var modal = $uibModal.open({
                        templateUrl: 'appCache/uiLoading.html',
                        backdrop: 'static',
                        keyboard: !1,
                        controller: ['$scope', '$uibModalInstance', 'options', function($scope, $uibModalInstance, options){
                            options.method(options.datas || {}).then($uibModalInstance.close, function(msg) {
                                $uibModalInstance.dismiss('服务异常，请稍后再试！');
                            });
                        }],
                        resolve: {
                            'options':function(){
                                return options;
                            }
                        }
                    });
                    return modal.result;
                },
                // window.prompt
                PROMPT: function() {

                },
                // 自定义loading画面
                loading: function(params) {
                    var dom = params.element || angular.element($window.document.getElementsByTagName('body')[0]),
                        hasTag = !!dom.getAttribute("app-loading");
                    if(hasTag) {
                        dom.children(".page-waiting");
                    }else {
                        var angularDomEl = angular.element('<div modal-backdrop></div>');
                    }
                    return {
                        open: function() {

                        },
                        close: function() {

                        }
                    }
                }
            }
        })();

        function UIService(params) {
            this.version = '2.0';
            this.constructor = UIService;
            var _this = this;
            if(appCommon.type(params) !== 'array') {
                this.extend(params);
            }else {
                params.map(function(obj) {
                    _this.extend(obj);
                });
            }
        }
        UIService.prototype.extend = function(obj) {
            angular.extend(this, this, obj)
        }

        return new UIService([appAjax, appDom, appWindow, appCommon]);

    }])
    //------------------------      缓存模板      -----------------------
    .run(["$templateCache", function($templateCache) {
        $templateCache.put("appCache/uiAlert.html",
        "<div class=\"popup_box {{className}}\">\n" +
        " <h1 class=\"popup_title\" ng-bind=\"headerTxt\"></h1>\n" +
        " <div class=\"popup_content\">\n" +
        "  <div class=\"popup_message\" ng-bind=\"message\"></div>\n" +
        "  <div class=\"popup_panel\">\n" +
        "   <input type=\"button\" ng-click=\"ok()\" value=\"&nbsp;确定&nbsp;\" class=\"popup_ok\">\n" +
        "  </div>\n" +
        " </div></div>");

        $templateCache.put("appCache/uiConfirm.html",
        "<div class=\"popup_box {{className}}\">\n" +
        " <h1 class=\"popup_title\" ng-bind=\"headerTxt\"></h1>\n" +
        " <div class=\"popup_content\">\n" +
        "  <div class=\"popup_message\" ng-bind=\"message\"></div>\n" +
        "  <div class=\"popup_panel\">\n" +
        "   <input type=\"button\" ng-click=\"cancel()\" value=\"&nbsp;取消&nbsp;\" class=\"popup_cancel\">\n" +
        "   <input type=\"button\" ng-click=\"ok()\" value=\"&nbsp;确定&nbsp;\" class=\"popup_ok\">\n" +
        "  </div>\n" +
        " </div></div>");

        $templateCache.put("appCache/uiLoading.html",
        "<div class=\"page-waiting\">\n" +
        " <div class=\"waitingBar\">\n" +
        " <img src=\"images/waiting.gif\"/>\n" +
        " </div></div>");

        $templateCache.put("appCache/contactTree.html",
        "<ul class=\"nav nav-stacked\" ng-model=\"ngScope\"> \n" +
        " <li class=\"item-li-box\" ng-repeat=\"department in departmentTree.children\" appaddress-item>\n" +
        "  <div class=\"item-box\" ng-class=\"{'active': department == currDepartment}\">\n" +
        "   <div class=\"item-title\" ng-click=\"onClickDepartment(department, $event)\" ng-bind=\"department.name\" title=\"{{department.name}}\"></div>\n" +
        "   <div class=\"item-icon1\">\n" +
        "    <span ng-hide=\"loadActive\" ng-click=\"clickAddressItem(department.id)\" class=\"appAddressImg app-icon\" ng-class=\"{'picon-menu-right':isShow==-1,'picon-nothing':isShow==0,'picon-menu-down':isShow==1}\"></span>\n" +
        "    <span class=\"appAddressImg app-icon picon-loading\" ng-show=\"loadActive\"></span>\n" +
        "   </div>\n" +
        "  </div>\n" +
        "  <div class=\"addressListBox\" ng-show=\"isShow==1\"  ng-model=\"department\" template-url=\"appCache/contactTree.html\"></div>\n" +
        " </li>\n" +
        "</ul>");
    }]);
